home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / ole2book.zip / CHAP11.ZIP / CHAP11 / POLYLINE / POLYLINE.CPP < prev    next >
C/C++ Source or Header  |  1993-06-22  |  17KB  |  736 lines

  1. /*
  2.  * POLYLINE.CPP
  3.  * Polyline Component Object Chapter 11
  4.  *
  5.  * Implementation of the CPolyline class that we expose as an
  6.  * OLE 2.0 component object.
  7.  *
  8.  * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
  9.  *
  10.  * Kraig Brockschmidt, Software Design Engineer
  11.  * Microsoft Systems Developer Relations
  12.  *
  13.  * Internet  :  kraigb@microsoft.com
  14.  * Compuserve:  >INTERNET:kraigb@microsoft.com
  15.  */
  16.  
  17.  
  18. #include "polyline.h"
  19.  
  20.  
  21. /*
  22.  * CPolyline:CPolyline
  23.  * CPolyline::~CPolyline
  24.  *
  25.  * Constructor Parameters:
  26.  *  punkOuter       LPUNKNOWN of the controlling unknown.
  27.  *  pfnDestroy      LPFNDESTROYED to call when an object is destroyed.
  28.  *  hInst           HINSTANCE of the application we're in.
  29.  */
  30.  
  31. CPolyline::CPolyline(LPUNKNOWN punkOuter, LPFNDESTROYED pfnDestroy
  32.     , HINSTANCE hInst)
  33.     {
  34.     m_hWnd=NULL;
  35.     m_hInst=hInst;
  36.  
  37.     m_cRef=0;
  38.     m_punkOuter=punkOuter;
  39.     m_pfnDestroy=pfnDestroy;
  40.     m_fDirty=FALSE;
  41.  
  42.     m_pST=NULL;
  43.     m_cf =0;
  44.  
  45.     m_clsID=CLSID_Polyline11;
  46.     m_iID  =IID_IPolyline6;
  47.  
  48.     //NULL any contained interfaces initially.
  49.     m_pIPolyline        =NULL;
  50.     m_pIPersistStorage  =NULL;
  51.  
  52.     m_pIDataObject      =NULL;
  53.     m_pIDataAdviseHolder=NULL;
  54.     m_pAdv              =NULL;
  55.  
  56.     //Initialize IDataObject::EnumFormatEtc arrays
  57.     m_cf=RegisterClipboardFormat(SZPOLYLINECLIPFORMAT);
  58.  
  59.     //CHAPTER11MOD
  60.     m_pDefIUnknown       =NULL;
  61.     m_pDefIOleObject     =NULL;
  62.     m_pDefIDataObject    =NULL;
  63.     m_pDefIViewObject    =NULL;
  64.     m_pDefIPersistStorage=NULL;
  65.  
  66.     m_pIOleAdviseHolder =NULL;
  67.     m_pIOleObject       =NULL;
  68.     m_pIOleClientSite   =NULL;
  69.     m_pIViewObject      =NULL;
  70.     m_pIAdviseSink      =NULL;
  71.  
  72.     m_dwFrozenAspects   =0;
  73.     m_dwAdviseAspects   =0;
  74.     m_dwAdviseFlags     =0;
  75.  
  76.     m_hDlg=NULL;
  77.     //End CHAPTER11MOD
  78.  
  79.     return;
  80.     }
  81.  
  82.  
  83. CPolyline::~CPolyline(void)
  84.     {
  85.     if (NULL!=m_pST)
  86.         delete m_pST;
  87.  
  88.     //CHAPTER11MOD
  89.     if (NULL!=m_hDlg)
  90.         DestroyWindow(m_hDlg);
  91.  
  92.     if (NULL!=m_pDefIUnknown)
  93.         m_pDefIUnknown->Release();
  94.  
  95.     if (NULL!=m_pDefIOleObject)
  96.         m_pDefIOleObject->Release();
  97.  
  98.     if (NULL!=m_pDefIViewObject)
  99.         m_pDefIViewObject->Release();
  100.  
  101.     if (NULL!=m_pDefIDataObject)
  102.         m_pDefIDataObject->Release();
  103.  
  104.     if (NULL!=m_pDefIPersistStorage)
  105.         m_pDefIPersistStorage->Release();
  106.  
  107.     if (NULL!=m_pIAdviseSink)
  108.         m_pIAdviseSink->Release();
  109.  
  110.     if (NULL!=m_pIViewObject)
  111.         delete m_pIViewObject;
  112.  
  113.     if (NULL!=m_pIOleClientSite)
  114.         m_pIOleClientSite->Release();
  115.  
  116.     if (NULL!=m_pIOleAdviseHolder)
  117.         m_pIOleAdviseHolder->Release();
  118.  
  119.     if (NULL!=m_pIOleObject)
  120.         delete m_pIOleObject;
  121.     //End CHAPTER11MOD
  122.  
  123.  
  124.     //Free our contained interfaces, delete those we own, Release others.
  125.     if (NULL!=m_pIDataAdviseHolder)
  126.         m_pIDataAdviseHolder->Release();
  127.  
  128.     if (NULL!=m_pIDataObject)
  129.         delete m_pIDataObject;
  130.  
  131.     if (NULL!=m_pIPersistStorage)
  132.         delete m_pIPersistStorage;
  133.  
  134.     if (NULL!=m_pIPolyline)
  135.         delete m_pIPolyline;
  136.  
  137.     //Reverses the AddRef in ::SetAdvise
  138.     if (NULL!=m_pAdv)
  139.         m_pAdv->Release();
  140.  
  141.     return;
  142.     }
  143.  
  144.  
  145.  
  146.  
  147. /*
  148.  * CPolyline::FInit
  149.  *
  150.  * Purpose:
  151.  *  Performs any intiailization of a CPolyline that's prone to failure
  152.  *  that we also use internally before exposing the object outside
  153.  *  this DLL.
  154.  *
  155.  * Parameters:
  156.  *  None
  157.  *
  158.  * Return Value:
  159.  *  BOOL            TRUE if the function is successful, FALSE otherwise.
  160.  */
  161.  
  162. BOOL CPolyline::FInit(void)
  163.     {
  164.     LPUNKNOWN       pIUnknown=(LPUNKNOWN)this;
  165.     HRESULT         hr;
  166.  
  167.     if (NULL!=m_punkOuter)
  168.         pIUnknown=m_punkOuter;
  169.  
  170.     m_pST=new CStringTable(m_hInst);
  171.  
  172.     if (!m_pST->FInit(IDS_POLYLINEMIN, IDS_POLYLINEMAX))
  173.         return FALSE;
  174.  
  175.     //Allocate contained interfaces.
  176.     m_pIPolyline=new CImpIPolyline(this, pIUnknown);
  177.  
  178.     if (NULL==m_pIPolyline)
  179.         return FALSE;
  180.  
  181.     m_pIPersistStorage=new CImpIPersistStorage(this, pIUnknown);
  182.  
  183.     if (NULL==m_pIPersistStorage)
  184.         return FALSE;
  185.  
  186.     m_pIDataObject=new CImpIDataObject(this, pIUnknown);
  187.  
  188.     if (NULL==m_pIDataObject)
  189.         return FALSE;
  190.  
  191.     //CHAPTER11MOD
  192.     m_pIOleObject=new CImpIOleObject(this, pIUnknown);
  193.  
  194.     if (NULL==m_pIOleObject)
  195.         return FALSE;
  196.  
  197.     m_pIViewObject=new CImpIViewObject(this, pIUnknown);
  198.  
  199.     if (NULL==m_pIViewObject)
  200.         return FALSE;
  201.  
  202.  
  203.     //Get stuff from the default handler so we get some free implementation
  204.     hr=OleCreateDefaultHandler(CLSID_Polyline11, pIUnknown, IID_IUnknown
  205.         , (LPLPVOID)&m_pDefIUnknown);
  206.  
  207.     if (FAILED(hr))
  208.         return FALSE;
  209.  
  210.     //Now try to get other interfaces to which we delegate
  211.     hr=m_pDefIUnknown->QueryInterface(IID_IOleObject
  212.         , (LPLPVOID)&m_pDefIOleObject);
  213.  
  214.     if (FAILED(hr))
  215.         return FALSE;
  216.  
  217.     hr=m_pDefIUnknown->QueryInterface(IID_IViewObject
  218.         , (LPLPVOID)&m_pDefIViewObject);
  219.  
  220.     if (FAILED(hr))
  221.         return FALSE;
  222.  
  223.     hr=m_pDefIUnknown->QueryInterface(IID_IDataObject
  224.         , (LPLPVOID)&m_pDefIDataObject);
  225.  
  226.     if (FAILED(hr))
  227.         return FALSE;
  228.  
  229.     hr=m_pDefIUnknown->QueryInterface(IID_IPersistStorage
  230.         , (LPLPVOID)&m_pDefIPersistStorage);
  231.  
  232.     if (FAILED(hr))
  233.         return FALSE;
  234.  
  235.     m_pIPolyline->New();
  236.     //End CHAPTER11MOD
  237.  
  238.     return TRUE;
  239.     }
  240.  
  241.  
  242.  
  243.  
  244.  
  245.  
  246.  
  247. /*
  248.  * CPolyline::QueryInterface
  249.  * CPolyline::AddRef
  250.  * CPolyline::Release
  251.  *
  252.  * Purpose:
  253.  *  IUnknown members for CPolyline object.
  254.  */
  255.  
  256. STDMETHODIMP CPolyline::QueryInterface(REFIID riid, LPVOID FAR *ppv)
  257.     {
  258.     *ppv=NULL;
  259.  
  260.     /*
  261.      * The only calls we get here for IUnknown are either in a non-aggregated
  262.      * case or when we're created in an aggregation, so in either we always
  263.      * return our IUnknown for IID_IUnknown.
  264.      */
  265.     if (IsEqualIID(riid, IID_IUnknown))
  266.         *ppv=(LPVOID)this;
  267.  
  268.     //For anything else we return contained interfaces.
  269.     if (IsEqualIID(riid, m_iID))
  270.         *ppv=(LPVOID)m_pIPolyline;
  271.  
  272.     if (IsEqualIID(riid, IID_IPersist) || IsEqualIID(riid, IID_IPersistStorage))
  273.         *ppv=(LPVOID)m_pIPersistStorage;
  274.  
  275.     if (IsEqualIID(riid, IID_IDataObject))
  276.         *ppv=(LPVOID)m_pIDataObject;
  277.  
  278.     //CHAPTER11MOD
  279.     if (IsEqualIID(riid, IID_IOleObject))
  280.         *ppv=(LPVOID)m_pIOleObject;
  281.  
  282.     if (IsEqualIID(riid, IID_IViewObject))
  283.         *ppv=(LPVOID)m_pIViewObject;
  284.  
  285.     //Use the default handler's cache.
  286.     if (IsEqualIID(riid, IID_IOleCache))
  287.         return m_pDefIUnknown->QueryInterface(riid, ppv);
  288.     //End CHAPTER11MOD
  289.  
  290.     //AddRef any interface we'll return.
  291.     if (NULL!=*ppv)
  292.         {
  293.         ((LPUNKNOWN)*ppv)->AddRef();
  294.         return NOERROR;
  295.         }
  296.  
  297.     return ResultFromScode(E_NOINTERFACE);
  298.     }
  299.  
  300.  
  301. STDMETHODIMP_(ULONG) CPolyline::AddRef(void)
  302.     {
  303.     return ++m_cRef;
  304.     }
  305.  
  306.  
  307. STDMETHODIMP_(ULONG) CPolyline::Release(void)
  308.     {
  309.     ULONG       cRefT;
  310.  
  311.     cRefT=--m_cRef;
  312.  
  313.     if (0==m_cRef)
  314.         delete this;
  315.  
  316.     return cRefT;
  317.     }
  318.  
  319.  
  320.  
  321.  
  322.  
  323.  
  324.  
  325. /*
  326.  * CPolyline::RectConvertMappings
  327.  *
  328.  * Purpose:
  329.  *  Converts the contents of a rectangle from device (MM_TEXT) or
  330.  *  HIMETRIC to the other.
  331.  *
  332.  * Parameters:
  333.  *  pRect           LPRECT containing the rectangle to convert.
  334.  *  fToDevice       BOOL TRUE to convert from HIMETRIC to device,
  335.  *                  FALSE to convert device to HIMETRIC.
  336.  *
  337.  * Return Value:
  338.  *  None
  339.  */
  340.  
  341. void CPolyline::RectConvertMappings(LPRECT pRect, BOOL fToDevice)
  342.     {
  343.     HDC      hDC;
  344.     int      iLpx, iLpy;
  345.  
  346.     if (NULL==pRect)
  347.         return;
  348.  
  349.     hDC=GetDC(NULL);
  350.     iLpx=GetDeviceCaps(hDC, LOGPIXELSX);
  351.     iLpy=GetDeviceCaps(hDC, LOGPIXELSY);
  352.     ReleaseDC(NULL, hDC);
  353.  
  354.     if (fToDevice)
  355.         {
  356.         pRect->left=MulDiv(iLpx, pRect->left, HIMETRIC_PER_INCH);
  357.         pRect->top =MulDiv(iLpy, pRect->top , HIMETRIC_PER_INCH);
  358.  
  359.         pRect->right =MulDiv(iLpx, pRect->right,  HIMETRIC_PER_INCH);
  360.         pRect->bottom=MulDiv(iLpy, pRect->bottom, HIMETRIC_PER_INCH);
  361.         }
  362.     else
  363.         {
  364.         pRect->left=MulDiv(pRect->left, HIMETRIC_PER_INCH, iLpx);
  365.         pRect->top =MulDiv(pRect->top , HIMETRIC_PER_INCH, iLpy);
  366.  
  367.         pRect->right =MulDiv(pRect->right,  HIMETRIC_PER_INCH, iLpx);
  368.         pRect->bottom=MulDiv(pRect->bottom, HIMETRIC_PER_INCH, iLpy);
  369.         }
  370.  
  371.     return;
  372.     }
  373.  
  374.  
  375.  
  376.  
  377. /*
  378.  * CPolyline::DataSet
  379.  *
  380.  * Purpose:
  381.  *  Sets the current data in this Polyline to a given structure.
  382.  *
  383.  * Parameters:
  384.  *  pplIn           LPPOLYLINEDATA to initialize to.
  385.  *  fSizeToData     BOOL indicating if we're to size to the data or scale it.
  386.  *  fNotify         BOOL indicating if we're to send an advise on this change.
  387.  *
  388.  * Return Value:
  389.  *  HRESULT         NOERROR if successful, otherwise a POLYLINE_E_ value.
  390.  */
  391.  
  392. STDMETHODIMP CPolyline::DataSet(LPPOLYLINEDATA pplIn, BOOL fSizeToData
  393.     , BOOL fNotify)
  394.     {
  395.     RECT            rc;
  396.  
  397.     /*
  398.      * Copy the structure in pplIn and repaint to reflect the new point
  399.      * set.  Note that unlike the RectSet message, we do no scaling,
  400.      * assuming that the rect in the structure is appropriate for the data.
  401.      */
  402.  
  403.     if (NULL==pplIn)
  404.         return ResultFromScode(POLYLINE_E_INVALIDPOINTER);
  405.  
  406.     //Preserve the old rectangle, then copy
  407.     rc=m_pl.rc;
  408.     m_pl=*pplIn;
  409.     m_fDirty=TRUE;
  410.  
  411.     /*
  412.      * If we're scaling the window to fit the data, then use
  413.      * RectSet passing our current rectangle as the new one.
  414.      * That makes sure that the data won't change but that the
  415.      * window is resized.
  416.      */
  417.  
  418.     if (fSizeToData)
  419.         {
  420.         POINT       pt;
  421.  
  422.         /*
  423.          * Get our offset in the parent window so we can RectSet
  424.          * to the right place since RectSet expects rectangle in
  425.          * parent coordinates and we get it in client coordinates.
  426.          */
  427.         GetWindowRect(m_hWnd, &rc);
  428.         pt.x=rc.left;
  429.         pt.y=rc.top;
  430.         ScreenToClient(GetParent(m_hWnd), &pt);
  431.         rc=m_pl.rc;
  432.         OffsetRect(&rc, pt.x, pt.y);
  433.  
  434.         //This will also cause a repaint.
  435.         m_pIPolyline->RectSet(&rc, fNotify);
  436.         }
  437.     else
  438.         {
  439.         //Make sure we're updated.
  440.         InvalidateRect(m_hWnd, NULL, TRUE);
  441.         UpdateWindow(m_hWnd);
  442.         }
  443.  
  444.     //CHAPTER11MOD
  445.     SendAdvise(OBJECTCODE_DATACHANGED);
  446.     //End CHAPTER11MOD
  447.  
  448.     return NOERROR;
  449.     }
  450.  
  451.  
  452.  
  453.  
  454.  
  455.  
  456.  
  457. /*
  458.  * CImpIPolyline::DataGet
  459.  *
  460.  * Purpose:
  461.  *  Retrieves the Polyline's current data.
  462.  *
  463.  * Parameters:
  464.  *  pplIn           LPPOLYLINEDATA into which we copy the data.
  465.  *
  466.  * Return Value:
  467.  *  HRESULT         NOERROR if successful, otherwise a POLYLINE_E_ value.
  468.  */
  469.  
  470. STDMETHODIMP CPolyline::DataGet(LPPOLYLINEDATA pplIn)
  471.     {
  472.     if (NULL==pplIn)
  473.         return ResultFromScode(POLYLINE_E_INVALIDPOINTER);
  474.  
  475.     *pplIn=m_pl;
  476.     return NOERROR;
  477.     }
  478.  
  479.  
  480.  
  481.  
  482.  
  483.  
  484. /*
  485.  * CPolyline::RenderNative
  486.  *
  487.  * Purpose:
  488.  *  Retrieves the Polyline's data in a global memory handle.
  489.  *
  490.  * Parameters:
  491.  *  phMem           HGLOBAL FAR * in which to store the handle.
  492.  *
  493.  * Return Value:
  494.  *  HRESULT         NOERROR if successful, otherwise a POLYLINE_E_ value.
  495.  */
  496.  
  497. STDMETHODIMP CPolyline::RenderNative(HGLOBAL FAR *phMem)
  498.     {
  499.     HGLOBAL         hMem;
  500.     LPPOLYLINEDATA  ppl;
  501.     HRESULT         hr=ResultFromScode(POLYLINE_E_INVALIDPOINTER);
  502.  
  503.     if (NULL==phMem)
  504.         return ResultFromScode(POLYLINE_E_INVALIDPOINTER);
  505.  
  506.     hMem=GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, CBPOLYLINEDATA);
  507.  
  508.     if (NULL!=hMem)
  509.         {
  510.         ppl=(LPPOLYLINEDATA)GlobalLock(hMem);
  511.         hr=DataGet(ppl);
  512.  
  513.         GlobalUnlock(hMem);
  514.  
  515.         if (FAILED(hr))
  516.             {
  517.             GlobalFree(hMem);
  518.             hMem=NULL;
  519.             }
  520.         }
  521.  
  522.     *phMem=hMem;
  523.     return hr;
  524.     }
  525.  
  526.  
  527.  
  528.  
  529. /*
  530.  * CPolyline::RenderBitmap
  531.  *
  532.  * Purpose:
  533.  *  Creates a bitmap image of the current Polyline.
  534.  *
  535.  * Parameters:
  536.  *  phBmp           HBITMAP FAR * in which to return the bitmap.
  537.  *
  538.  * Return Value:
  539.  *  HRESULT         NOERROR if successful, otherwise a POLYLINE_E_ value.
  540.  */
  541.  
  542. STDMETHODIMP CPolyline::RenderBitmap(HBITMAP FAR *phBmp)
  543.     {
  544.     HDC             hDC;
  545.     HDC             hMemDC;
  546.     HBITMAP         hBmp;
  547.     RECT            rc;
  548.     HGDIOBJ         hObj;
  549.  
  550.     if (NULL==phBmp)
  551.         return ResultFromScode(POLYLINE_E_INVALIDPOINTER);
  552.  
  553.     //Render a bitmap the size of the current rectangle.
  554.     hDC=GetDC(m_hWnd);
  555.     hMemDC=CreateCompatibleDC(hDC);
  556.  
  557.     GetClientRect(m_hWnd, &rc);
  558.     hBmp=CreateCompatibleBitmap(hDC, rc.right, rc.bottom);
  559.  
  560.     if (NULL!=hBmp)
  561.         {
  562.         //Draw the POLYLINEDATA into the bitmap.
  563.         hObj=SelectObject(hMemDC, hBmp);
  564.         Draw(hMemDC, FALSE, TRUE, &rc, NULL);
  565.         SelectObject(hMemDC, hObj);
  566.         }
  567.  
  568.     DeleteDC(hMemDC);
  569.     ReleaseDC(m_hWnd, hDC);
  570.  
  571.     *phBmp=hBmp;
  572.     return NOERROR;
  573.     }
  574.  
  575.  
  576.  
  577.  
  578.  
  579.  
  580.  
  581. /*
  582.  * CPolyline::RenderMetafilePict
  583.  *
  584.  * Purpose:
  585.  *  Renders the current Polyline into a METAFILEPICT structure in
  586.  *  global memory.
  587.  *
  588.  * Parameters:
  589.  *  phMem           HGLOBAL FAR * in which to return the METAFILEPICT.
  590.  *
  591.  * Return Value:
  592.  *  HRESULT         NOERROR if successful, otherwise a POLYLINE_E_ value.
  593.  */
  594.  
  595. STDMETHODIMP CPolyline::RenderMetafilePict(HGLOBAL FAR * phMem)
  596.     {
  597.     HGLOBAL         hMem;
  598.     HMETAFILE       hMF;
  599.     HDC             hDC;
  600.     LPMETAFILEPICT  pMF;
  601.     RECT            rc;
  602.  
  603.     if (NULL==phMem)
  604.         return ResultFromScode(POLYLINE_E_INVALIDPOINTER);
  605.  
  606.     hMF=NULL;
  607.  
  608.     //Create a memory metafile and return its handle.
  609.     hDC=(HDC)CreateMetaFile(NULL);
  610.  
  611.     if (NULL==hDC)
  612.         return ResultFromScode(STG_E_MEDIUMFULL);
  613.  
  614.     SetMapMode(hDC, MM_ANISOTROPIC);
  615.     GetClientRect(m_hWnd, &rc);
  616.     SetWindowOrg(hDC, 0, 0);
  617.     SetWindowExt(hDC, rc.right, rc.bottom);
  618.  
  619.     Draw(hDC, TRUE, TRUE, &rc, NULL);
  620.     hMF=CloseMetaFile(hDC);
  621.  
  622.     if (NULL==hMF)
  623.         return ResultFromScode(STG_E_MEDIUMFULL);
  624.  
  625.     //Allocate the METAFILEPICT structure.
  626.     hMem=GlobalAlloc(GMEM_DDESHARE | GMEM_MOVEABLE, sizeof(METAFILEPICT));
  627.  
  628.     if (NULL==hMem)
  629.         {
  630.         DeleteMetaFile(hMF);
  631.         return ResultFromScode(E_FAIL);
  632.         }
  633.  
  634.     /*
  635.      * Global lock only fails in PMODE if the selector is invalid
  636.      * (like it was discarded) or references a 0 length segment,
  637.      * neither of which can happen here.
  638.      */
  639.     pMF=(LPMETAFILEPICT)GlobalLock(hMem);
  640.  
  641.     pMF->hMF=hMF;
  642.     pMF->mm=MM_ANISOTROPIC;
  643.  
  644.     //Insert the extents in MM_HIMETRIC units.
  645.     GetClientRect(m_hWnd, &rc);
  646.     RectConvertMappings(&rc, FALSE);
  647.     pMF->xExt=rc.right;
  648.     pMF->yExt=rc.bottom;
  649.  
  650.     GlobalUnlock(hMem);
  651.  
  652.     *phMem=hMem;
  653.     return NOERROR;
  654.     }
  655.  
  656.  
  657.  
  658. //CHAPTER11MOD
  659. /*
  660.  * CFigure::SendAdvise
  661.  *
  662.  * Purpose:
  663.  *  Calls the appropriate IOleClientSite or IAdviseSink member function
  664.  *  for various events such as closure, renaming, saving, etc.
  665.  *
  666.  * Parameters:
  667.  *  uCode           UINT OBJECTCODE_* identifying the notification.
  668.  *
  669.  * Return Value:
  670.  *  None
  671.  */
  672.  
  673. void CPolyline::SendAdvise(UINT uCode)
  674.     {
  675.     DWORD       dwAspect=DVASPECT_CONTENT | DVASPECT_THUMBNAIL;
  676.  
  677.     switch (uCode)
  678.         {
  679.         case OBJECTCODE_SAVED:
  680.             if (NULL!=m_pIOleAdviseHolder)
  681.                 m_pIOleAdviseHolder->SendOnSave();
  682.             break;
  683.  
  684.         case OBJECTCODE_CLOSED:
  685.             if (NULL!=m_pIOleAdviseHolder)
  686.                 m_pIOleAdviseHolder->SendOnClose();
  687.  
  688.             break;
  689.  
  690.         case OBJECTCODE_RENAMED:
  691.             //Call IOleAdviseHolder::SendOnRename (later)
  692.             break;
  693.  
  694.         case OBJECTCODE_SAVEOBJECT:
  695.             if (m_fDirty && NULL!=m_pIOleClientSite)
  696.                 m_pIOleClientSite->SaveObject();
  697.  
  698.             break;
  699.  
  700.         case OBJECTCODE_DATACHANGED:
  701.             //No flags are necessary here.
  702.             if (NULL!=m_pIDataAdviseHolder)
  703.                 m_pIDataAdviseHolder->SendOnDataChange(m_pIDataObject, 0, 0);
  704.  
  705.             if (NULL!=m_pIAdviseSink & (dwAspect & m_dwAdviseAspects))
  706.                 m_pIAdviseSink->OnViewChange(dwAspect & m_dwAdviseAspects, 0);
  707.  
  708.             break;
  709.  
  710.         case OBJECTCODE_SHOWWINDOW:
  711.             if (NULL!=m_pIOleClientSite)
  712.                 m_pIOleClientSite->OnShowWindow(TRUE);
  713.  
  714.             break;
  715.  
  716.         case OBJECTCODE_HIDEWINDOW:
  717.             if (NULL!=m_pIOleClientSite)
  718.                 m_pIOleClientSite->OnShowWindow(FALSE);
  719.  
  720.             break;
  721.  
  722.         case OBJECTCODE_SHOWOBJECT:
  723.             if (NULL!=m_pIOleClientSite)
  724.                 m_pIOleClientSite->ShowObject();
  725.  
  726.             break;
  727.         }
  728.  
  729.     return;
  730.     }
  731.  
  732.  
  733.  
  734.  
  735. //End CHAPTER11MOD
  736.